const fs = require('fs').promises;
const path = require('path');

const eventsDir = path.join(__dirname, '../../database/events');

// 获取所有事件列表
async function getAllEvents() {
  try {
    const files = await fs.readdir(eventsDir);
    const eventFiles = files.filter(file => file.endsWith('.json'));
    
    const events = await Promise.all(
      eventFiles.map(async (file) => {
        const data = await fs.readFile(path.join(eventsDir, file), 'utf8');
        return JSON.parse(data);
      })
    );
    
    return events;
  } catch (error) {
    if (error.code === 'ENOENT') {
      // 目录不存在，创建目录并返回空数组
      await fs.mkdir(eventsDir, { recursive: true });
      return [];
    }
    throw error;
  }
}

// 根据ID获取事件
async function getEventById(id) {
  try {
    const filePath = path.join(eventsDir, `${id}.json`);
    const data = await fs.readFile(filePath, 'utf8');
    return JSON.parse(data);
  } catch (error) {
    if (error.code === 'ENOENT') {
      return null;
    }
    throw error;
  }
}

// 创建新事件
async function createEvent(eventData) {
  try {
    const filePath = path.join(eventsDir, `${eventData.id}.json`);
    await fs.writeFile(filePath, JSON.stringify(eventData, null, 2), 'utf8');
    return eventData;
  } catch (error) {
    throw error;
  }
}

// 更新事件
async function updateEvent(id, eventData) {
  try {
    const filePath = path.join(eventsDir, `${id}.json`);
    // 检查文件是否存在
    await fs.access(filePath);
    
    await fs.writeFile(filePath, JSON.stringify(eventData, null, 2), 'utf8');
    return eventData;
  } catch (error) {
    if (error.code === 'ENOENT') {
      return null;
    }
    throw error;
  }
}

// 删除事件
async function deleteEvent(id) {
  try {
    const filePath = path.join(eventsDir, `${id}.json`);
    await fs.unlink(filePath);
    return true;
  } catch (error) {
    if (error.code === 'ENOENT') {
      return false;
    }
    throw error;
  }
}

// 获取指定分类下的事件
async function getEventsByCategory(categoryId) {
  try {
    const events = await getAllEvents();
    return events.filter(event => event.categoryId === categoryId);
  } catch (error) {
    throw error;
  }
}

/**
 * 更新事件模型架构
 * 为所有现有事件添加versionReferences字段
 * @returns {Promise<number>} 更新的事件数量
 */
async function updateEventSchema() {
  try {
    const events = await getAllEvents();
    let updatedCount = 0;
    
    for (const event of events) {
      // 如果事件没有versionReferences字段，添加一个空数组
      if (!event.versionReferences) {
        event.versionReferences = [];
        
        // 从节点中提取自定义节点类型信息
        if (event.nodes && Array.isArray(event.nodes)) {
          // 创建一个集合用于存储所有找到的自定义节点类型ID，避免重复
          const customNodeTypeIds = new Set();
          
          for (const node of event.nodes) {
            if (node.type === 'custom' && node.customNodeTypeId) {
              customNodeTypeIds.add(node.customNodeTypeId);
            }
          }
          
          // 添加到versionReferences中
          for (const nodeTypeId of customNodeTypeIds) {
            if (node.customNodeVersionId) {
              event.versionReferences.push({
                versionId: node.customNodeVersionId,
                nodeTypeId: nodeTypeId
              });
            }
          }
        }
        
        // 保存修改后的事件
        await fs.writeFile(
          path.join(eventsDir, `${event.id}.json`),
          JSON.stringify(event, null, 2),
          'utf8'
        );
        
        updatedCount++;
      }
    }
    
    return updatedCount;
  } catch (error) {
    throw error;
  }
}

/**
 * 根据版本ID获取引用该版本的所有事件
 * @param {string} versionId - 版本ID
 * @returns {Promise<Array>} 引用该版本的事件数组
 */
async function getEventsByVersionId(versionId) {
  try {
    const events = await getAllEvents();
    return events.filter(event => 
      event.versionReferences && 
      event.versionReferences.some(ref => ref.versionId === versionId)
    );
  } catch (error) {
    throw error;
  }
}

/**
 * 添加版本引用到事件
 * @param {string} eventId - 事件ID
 * @param {string} versionId - 版本ID
 * @param {string} nodeTypeId - 节点类型ID
 * @returns {Promise<Object|null>} 更新后的事件或null
 */
async function addVersionReference(eventId, versionId, nodeTypeId) {
  try {
    const event = await getEventById(eventId);
    if (!event) return null;
    
    // 确保versionReferences存在
    if (!event.versionReferences) {
      event.versionReferences = [];
    }
    
    // 检查是否已存在相同的引用
    const existingRef = event.versionReferences.find(
      ref => ref.versionId === versionId && ref.nodeTypeId === nodeTypeId
    );
    
    if (!existingRef) {
      event.versionReferences.push({
        versionId,
        nodeTypeId
      });
      
      // 保存更新后的事件
      await updateEvent(eventId, event);
    }
    
    return event;
  } catch (error) {
    throw error;
  }
}

/**
 * 从事件中移除版本引用
 * @param {string} eventId - 事件ID
 * @param {string} versionId - 版本ID
 * @returns {Promise<Object|null>} 更新后的事件或null
 */
async function removeVersionReference(eventId, versionId) {
  try {
    const event = await getEventById(eventId);
    if (!event || !event.versionReferences) return null;
    
    // 过滤掉指定的版本引用
    event.versionReferences = event.versionReferences.filter(
      ref => ref.versionId !== versionId
    );
    
    // 保存更新后的事件
    await updateEvent(eventId, event);
    return event;
  } catch (error) {
    throw error;
  }
}

module.exports = {
  getAllEvents,
  getEventById,
  createEvent,
  updateEvent,
  deleteEvent,
  getEventsByCategory,
  updateEventSchema,
  getEventsByVersionId,
  addVersionReference,
  removeVersionReference
}; 